package models

import (
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

// 发送任务 和机器的关系
// 1对多 机器只能属于1个发送任务
// 新建发送任务 就需要填入ip
// 主配置文件池
// job 对象 机器：ip+port
//
//	2 k8s 的服务发现：集群外部发送
type MonitorSendGroup struct {
	Model         // 不用每次写ID 和 createAt了
	Name   string `json:"name" validate:"required,min=1,max=50" gorm:"uniqueIndex;type:varchar(100);comment:分组英文名称 给AlertManager配置文件使用，支持使用通配符*进行模糊搜索" `
	NameZh string `json:"nameZh" validate:"required,min=1,max=50" gorm:"uniqueIndex;type:varchar(100);comment:分组中文名称 告警规则选择发送组的时候 select用的，支持使用通配符*进行模糊搜索" `
	Enable int    `json:"enable" gorm:"comment:是否被开启 1正常 2关闭"` //用户是否被冻结 1正常 2冻结
	// D:\nyy_work\go_path\src\github.com\prometheus\alertmanager\config\config.go
	UserID uint
	// 公共的
	PoolId        uint `json:"poolId" gorm:"comment:关联哪个AlertManager实例的"`
	OnDutyGroupId uint `json:"onDutyGroupId" gorm:"comment:值班表 在im中是发到群组里面 at值班人 或者 再私聊发生给值班人"`

	// 静态接收人 没有配置
	StaticReceiveUsers  []*User     `json:"staticReceiveUsers" gorm:"many2many:static_receive_users;comment:静态配置的接收人列表"` // 多对多
	FeishuQunRobotToken string      `json:"feishuQunRobotToken" gorm:"comment: im飞书机器人token 对应的是哪个im群"`
	RepeatInterval      string      `json:"repeatInterval" gorm:"comment: 默认重复发送时间"`
	SendResolved        int         `json:"sendResolved" gorm:"comment:是否被开启 1=true发送 2=false 不发送"` //用户是否被冻结 1正常 2冻结
	NotifyMethods       StringArray `json:"notifyMethods" gorm:"comment: 通知方法 ：email im phone sms 组合"`

	// 告警升级的配置
	NeedUpgrade        int     `json:"needUpgrade" gorm:"comment:是否告警升级 1=true升级 2=false 不升级"`                 //用户是否被冻结 1正常 2冻结
	FirstUpgradeUsers  []*User `json:"firstUpgradeUsers" gorm:"many2many:first_upgrade_users;comment:第一升级人列表"` // 多对多
	UpgradeMinutes     int     `json:"upgradeMinutes" gorm:"comment: 告警多久没恢复就升级"`
	SecondUpgradeUsers []*User `json:"secondUpgradeUsers" gorm:"many2many:second_upgrade_users;comment:第二升级人列表"` // 多对多

	// 静态人和升级的关系
	TreeNodeIdInts  []int    `json:"treeNodeIdInts" gorm:"-"`
	FirstUserNames  []string `json:"firstUserNames" gorm:"-"`
	Key             string   `json:"key" gorm:"-"`             //给前端表格
	PoolName        string   `json:"poolName" gorm:"-"`        //给前端表格
	OnDutyGroupName string   `json:"onDutyGroupName" gorm:"-"` //给前端表格
	CreateUserName  string   `json:"createUserName" gorm:"-"`
}

func (obj *MonitorSendGroup) Create() error {
	return Db.Create(obj).Error

}
func (obj *MonitorSendGroup) DeleteOne() error {

	return Db.Select(clause.Associations).Unscoped().Delete(obj).Error

}

func (obj *MonitorSendGroup) CreateOne() error {
	return Db.Create(obj).Error

}

func (obj *MonitorSendGroup) UpdateFirstUpgradeUsers() error {

	return Db.Model(obj).Association("FirstUpgradeUsers").Replace(obj.FirstUpgradeUsers)
}

// 事务中的update
// 1. 先删除原有的 升级人
// 2. 然后更新 新的升级人
// 3. 更新自己的字段
func (obj *MonitorSendGroup) TransactionUpdate(firstUpgradeUsers []*User) error {
	return Db.Transaction(func(tx *gorm.DB) error {
		// 1. 先删除原有的 升级人
		//err := tx.Select(clause.Associations).Unscoped().Delete(obj).Error
		//if err != nil {
		//	return err
		//}

		//  2. 然后更新 新的升级人
		err := tx.Model(obj).Association("FirstUpgradeUsers").Replace(firstUpgradeUsers)
		if err != nil {
			return err
		}

		// 3. 更新自己的字段
		err = tx.Where("id = ?", obj.ID).Updates(obj).Error
		if err != nil {
			return err
		}
		return nil
	})
}

func (obj *MonitorSendGroup) UpdateOne() error {
	return Db.Debug().Where("id = ?", obj.ID).Updates(obj).Error

}

func (obj *MonitorSendGroup) FillFrontAllData() {
	dbUser, _ := GetUserById(int(obj.UserID))
	if dbUser != nil {
		obj.CreateUserName = dbUser.Username
	}
	obj.FirstUserNames = commonGetUserNamesByUsers(obj.FirstUpgradeUsers)

	dbOnDutyGroup, _ := GetMonitorOndutyGroupById(int(obj.OnDutyGroupId))
	if dbOnDutyGroup != nil {
		obj.OnDutyGroupName = dbOnDutyGroup.Name
	}

	dbPool, _ := GetMonitorAlertmanagerPoolById(int(obj.PoolId))
	if dbPool != nil {
		obj.PoolName = dbPool.Name
	}

	obj.Key = fmt.Sprintf("%d", obj.ID)
	ids := []int{}

	obj.TreeNodeIdInts = ids

}
func GetMonitorSendGroupAll() (objs []*MonitorSendGroup, err error) {
	err = Db.Preload("FirstUpgradeUsers").Find(&objs).Error
	return
}

func GetMonitorSendGroupCount() int {
	var count int64
	Db.Table("form_designs").Count(&count)
	return int(count)
}

func GetMonitorSendGroupByLevel(level int) (objs []*MonitorSendGroup, err error) {
	err = Db.Where("level = ?", level).Preload("OpsAdmins").Find(&objs).Error
	return
}

// select * from ecs where
func GetMonitorSendGroupByIdsWithLimitOffset(ids []int, limit, offset int) (objs []*MonitorSendGroup, err error) {
	err = Db.Limit(limit).Offset(offset).Preload("FirstUpgradeUsers").Find(&objs, ids).Error
	return
}

// 查询这个节点池管理的发送Job
func GetMonitorSendGroupByPoolId(poolId uint) (objs []*MonitorSendGroup, err error) {

	//err = Db.Where("enable=1 and pool_id = ?", poolId).Find(&objs).Error
	err = Db.Where(" pool_id = ?", poolId).Find(&objs).Error
	return

}

func GetMonitorSendGroupByOndutyGroupId(ondutyGroup uint) (objs []*MonitorSendGroup, err error) {

	err = Db.Where(" on_duty_group_id = ?", ondutyGroup).Find(&objs).Error
	return

}

func GetMonitorSendGroupById(id int) (*MonitorSendGroup, error) {

	var dbObj MonitorSendGroup
	err := Db.Where("id = ?", id).First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("MonitorSendGroup不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil

}
